﻿    public class GlobalExceptionMiddleware
    {
        private readonly RequestDelegate _next; //用来处理上下文请求  

        public GlobalExceptionMiddleware(RequestDelegate next)
        {
            _next = next;
        }
        /// <summary>
        /// 执行中间件
        /// </summary>
        /// <param name="httpContext"></param>
        /// <returns></returns>
        public async Task InvokeAsync(HttpContext httpContext)
        {
            try
            {
                await _next(httpContext); //要么在中间件中处理，要么被传递到下一个中间件中去
            }
            catch (Exception ex)
            {
                await HandleExceptionAsync(httpContext, ex); // 捕获异常了 在HandleExceptionAsync中处理
            }
        }

        /// <summary>
        /// 异步处理异常
        /// </summary>
        /// <param name="context"></param>
        /// <param name="ex"></param>
        /// <returns></returns>
        private async Task HandleExceptionAsync(HttpContext context, Exception ex)
        {
            int code = (int)ResultCode.GLOBAL_ERROR;
            string msg;
            string error = string.Empty;
            //自定义异常
            if (ex is CustomException customException)
            {
                code = customException.code;
                msg = customException.Message;
                error = customException.logMsg;
            }
            else if (ex is ArgumentException)//参数异常
            {
                code = (int)ResultCode.PARAM_ERROR;
                msg = ex.Message;
            }
            else
            {
                msg = "Server Error,Please Contact with admin";
                error = $"{ex.Message}";
                context.Response.StatusCode = 500;
            }
            var options = new JsonSerializerOptions
            {
                //指定编码器使用 UnsafeRelaxedJsonEscaping，它允许在生成 JSON 字符串时不进行严格的转义验证。这意味着某些特殊字符（例如控制字符）可能不会被转义。
                Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
                //指定属性命名策略为 CamelCase，这将使属性名以小写字母开头，并使用驼峰命名风格。
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                //指定是否将生成的 JSON 格式化为带缩进的可读格式。将其设置为 true 可以增加可读性，但会产生更多的空白字符。
                WriteIndented = true
            };
            ApiResult apiResult = new(code, msg);
            string responseResult = System.Text.Json.JsonSerializer.Serialize(apiResult, options);
            await context.Response.WriteAsync(responseResult, System.Text.Encoding.UTF8);
    }

        public static Microsoft.AspNetCore.Http.Endpoint GetEndpoint(HttpContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            return context.Features.Get<IEndpointFeature>()?.Endpoint;
        }

    }
